﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows;
using System.Windows.Forms;
using FxSuperCore.Log;
using FxSuperCore.Utils;
using FxWinSuper.Functions;
using FxWinSuper.Plugin.Data;
using FxWinSupper.Config.Model;
using FxWinSuper.Util;
using FxWinSupper.Config;
using MessageBox = HandyControl.Controls.MessageBox;

namespace FxWinSuper.Plugin
{
	internal static class PluginController
	{
		public static readonly string PluginPath = Path.Combine(Environment.CurrentDirectory, "plugin");
		private static readonly List<PluginInfo> _pluginInfos = new List<PluginInfo>();
		private static ILogPrint Logger = InternalLog.Instance;

		/// <summary>
		/// 插件加载完成事件
		/// </summary>
		public static event Action PluginLoadComplete;

		/// <summary>
		/// 插件状态改变事件
		/// </summary>
		public static event Action<LocalPluginEntity> PluginStatueChanged;

		/// <summary>
		/// 插件卸载事件
		/// </summary>
		public static event Action<LocalPluginEntity> PluginUninstalled;

		public static void LoadPlugins()
		{
			Logger.Info("Start Load Plugins");
			// 1. 处理待删除、待更新的插件
			HandleSpecailStatusPlugin();
			// 2. 扫描插件目录
			ScanAllPlugin();
			// 3. 与配置文件同步扫描到的插件信息
			SyncPluginInfos();
			// 4. 初始化插件
			EnterPlugins();
			// 5. 持久化配置
			Conf.SaveConf();
			// 6. 触发加载完成事件
			PluginLoadComplete?.Invoke();
		}

		/// <summary>
		/// 与配置文件同步插件信息
		/// </summary>
		private static void SyncPluginInfos()
		{
			foreach (PluginInfo pluginInfo in _pluginInfos)
			{
				if (!Conf.DelayPluginHandleInfos.ContainsKey(pluginInfo.PluginName))
				{
					// 不在配置文件则为首次安装状态
					Conf.DelayPluginHandleInfos.Add(pluginInfo.PluginName, new SpecialHandlePluginInfo(pluginInfo.PluginName, PluginSpecialStatus.INSTALL));
					continue;
				}

				// 检测插件状态
				SpecialHandlePluginInfo specialHandlePluginInfo = Conf.DelayPluginHandleInfos[pluginInfo.PluginName];
				if (specialHandlePluginInfo.PluginStatus != PluginSpecialStatus.NORMAL &&
				    specialHandlePluginInfo.PluginStatus != PluginSpecialStatus.INSTALL &&
				    specialHandlePluginInfo.PluginStatus != PluginSpecialStatus.DISABLE)
				{
					Logger.Error($"插件状态异常，插件名:[{pluginInfo.PluginName}], 状态:[{specialHandlePluginInfo.PluginStatus}]");
					CommonUtils.ShowWinToast("错误", $"加载插件时存在插件状态异常，插件名:[{pluginInfo.PluginName}], 状态:[{specialHandlePluginInfo.PluginStatus}]", ToolTipIcon.Error);
					Environment.Exit(1);
				}
			}

			// 检测配置文件中残留的插件
			var specialHandlePluginInfos = new Dictionary<string, SpecialHandlePluginInfo>(Conf.DelayPluginHandleInfos);
			specialHandlePluginInfos.Keys.ToList().ForEach(pluginName =>
			{
				if (_pluginInfos.All(plugin => plugin.PluginName != pluginName))
				{
					Conf.DelayPluginHandleInfos.Remove(pluginName);
				}
			});
		}

		/// <summary>
		/// 初始化所有插件
		/// </summary>
		public static void EnterPlugins()
		{
			int loadCount = 0;
			_pluginInfos.SortWithBootstrapPriority();
			_pluginInfos.ForEach(plugin =>
			{
				SpecialHandlePluginInfo specialHandlePluginInfo = Conf.DelayPluginHandleInfos[plugin.PluginName];
				if (!plugin.Loaded && !plugin.Disabled && plugin.PluginAssembleInfo.DependencySoftwareVersionCode <= Conf.VersionCode)
				{
					try
					{
						if (specialHandlePluginInfo.PluginStatus == PluginSpecialStatus.INSTALL)
						{
							plugin.PluginInterface.Install();
						}
						plugin.PluginInterface.Enter();
						plugin.Loaded = true;
						specialHandlePluginInfo.PluginStatus = PluginSpecialStatus.NORMAL;
						loadCount++;
					}
					catch (Exception e)
					{
						Logger.Error($"初始化插件失败: {e.Message}");
						CommonUtils.ShowWinToast("错误", $"初始化插件失败:{e.Message}", ToolTipIcon.Error);
					}
				}
				Logger.Debug($"插件[{plugin.PluginName}]加载成功");
			});
			Logger.Debug($"本次共成功加载{loadCount}个插件");
		}

		/// <summary>
		/// 读取配置文件，处理处于特殊状态的插件（待删除/待更新）
		/// </summary>
		private static void HandleSpecailStatusPlugin()
		{
			var specialHandlePluginInfos = new Dictionary<string, SpecialHandlePluginInfo>(Conf.DelayPluginHandleInfos);
			foreach (var specialHandlePluginInfo in specialHandlePluginInfos)
			{
				SpecialHandlePluginInfo pluginInfo = specialHandlePluginInfo.Value;
				string pluginPath = Path.Combine(PluginPath, pluginInfo.PluginName);
				if (pluginInfo.PluginStatus == PluginSpecialStatus.WAIT_DELETE)
				{
					if (Directory.Exists(pluginPath))
					{
						try
						{
							// 删除插件目录
							Directory.Delete(pluginPath, true);
							Conf.DelayPluginHandleInfos.Remove(specialHandlePluginInfo.Key);
						}
						catch (FileNotFoundException e)
						{
							Conf.DelayPluginHandleInfos.Remove(specialHandlePluginInfo.Key);
							Logger.Warnning($"待删插件已经不存在, 详情:{e.Message}");
						}
						catch (Exception e)
						{
							Logger.Error($"删除插件失败,插件名:[{pluginInfo.PluginName}],详情:{e.Message}");
							CommonUtils.ShowWinToast("错误", $"删除插件失败,插件名:[{pluginInfo.PluginName}],详情:{e.Message}", ToolTipIcon.Error);
						}
					}
					continue;
				}
				// 等待更新插件
				if (pluginInfo.PluginStatus == PluginSpecialStatus.WAIT_UPDATE)
				{
					try
					{
						string pluginZipPath = GeneratePluginPackagePath(pluginInfo.PluginName);
						DetectPluginZipValid(pluginInfo.PluginName, pluginZipPath);
						if (Directory.Exists(pluginPath))
						{
							// 删除插件目录
							Directory.Delete(pluginPath, true);
						}
						Directory.CreateDirectory(pluginPath);
						using (var zip = ZipFile.OpenRead(pluginZipPath))
						{
							zip.ExtractToDirectory(pluginPath, true);
						}
						File.Delete(pluginZipPath);
						// 更新插件状态为首次安装
						pluginInfo.PluginStatus = PluginSpecialStatus.INSTALL;
					}
					catch (Exception e)
					{
						Logger.Error($"更新插件失败,插件名:[{pluginInfo.PluginName}],详情:{e.Message}");
						CommonUtils.ShowWinToast("错误", $"更新插件失败,插件名:[{pluginInfo.PluginName}],详情:{e.Message}", ToolTipIcon.Error);
					}
					continue;
				}
			}
		}

		/// <summary>
		/// 检测插件zip包是否合法
		/// zip包需要满足 {pluginName}.zip => {pluginName}.dll(一层目录下必须有个同名的.dll文件)
		/// </summary>
		private static void DetectPluginZipValid(string pluginName, string pluginZipPath)
		{
			if (!File.Exists(pluginZipPath))
			{
				throw new FileNotFoundException($"未获取到插件包:[{pluginZipPath}]");
			}
			using (var zip = ZipFile.OpenRead(pluginZipPath))
			{
				ZipArchiveEntry dllArchiveEntry = zip.Entries
					.FirstOrDefault(entry => !entry.FullName.Contains("/") && entry.Name == $"{pluginName}.dll");
				if (dllArchiveEntry == null)
				{
					throw new Exception($"插件包:[{Path.GetFileName(pluginZipPath)}]格式不正确，未在插件包根目录获取到同名dll文件");
				}
			}
		}

		/// <summary>
		/// 程序退出时，退出所有插件
		/// </summary>
		public static void ExitPlugins()
		{
			try
			{
				_pluginInfos.SortWithBootstrapLower();
				for (var i = _pluginInfos.Count - 1; i >= 0; i--)
				{
					var plugin = _pluginInfos[i];
					if (plugin.Loaded)
					{
						plugin.PluginInterface.Exit();
						plugin.Loaded = false;
					}
				}
			}
			catch (Exception e)
			{
				Logger.Error($"插件退出时发生错误:{e.Message}");
				CommonUtils.ShowWinToast("错误", $"插件退出时发生错误:{e.Message}",ToolTipIcon.Error);
			}
		}

		/// <summary>
		/// 扫描插件目录下所有插件
		/// </summary>
		private static void ScanAllPlugin()
		{
			List<string> pluginDirs = Directory.GetDirectories(PluginPath).ToList();
			foreach (var pluginDir in pluginDirs)
			{
				if (!Directory.Exists(pluginDir))
				{
					continue;
				}

				DirectoryInfo directoryInfo = new DirectoryInfo(pluginDir);
				if (_pluginInfos.Any(plugin => plugin.PluginName == directoryInfo.Name))
				{
					continue;
				}
				FileInfo dllFile = directoryInfo.GetFiles().FirstOrDefault(file => file.Name == directoryInfo.Name + ".dll");
				if (dllFile != null)
				{
					try
					{
						_pluginInfos.Add(GetPluginInfo(dllFile.FullName));
					}
					catch (Exception e)
					{
						StringBuilder sb = new StringBuilder();
						if (e is ReflectionTypeLoadException lodeException)
						{
							foreach (Exception excep in lodeException.LoaderExceptions)
							{
								sb.AppendLine(excep.Message);
							}
						}
						else
						{
							sb.Append(e.Message);
						}
						Logger.Error($"插件:[{directoryInfo.Name}]加载失败,详情:{sb}, {e.StackTrace}");
						CommonUtils.ShowWinToast("提示", $"插件:[{directoryInfo.Name}]加载失败");
					}
					continue;
				}

				Logger.Warnning($"未在[{directoryInfo.Name}]插件目录中获取到同名动态链接库文件，放弃加载该插件");
			}
			Logger.Debug($"共扫描到{_pluginInfos.Count}个插件");
		}

		/// <summary>
		/// 根据插件名，获取插件zip包路径
		/// </summary>
		/// <param name="pluginName">插件名</param>
		/// <returns>插件zip包路径</returns>
		public static string GeneratePluginPackagePath(string pluginName)
		{
			return Path.Combine(PluginPath, $"{pluginName}.zip");
		}

		/// <summary>
		/// 按bootsrap优先排序插件表
		/// </summary>
		private static void SortWithBootstrapPriority(this List<PluginInfo> pluginInfos)
		{
			pluginInfos.Sort((p1, p2) =>
			{
				return p2.PluginAssembleInfo.BootStrapPlugin.CompareTo(p1.PluginAssembleInfo.BootStrapPlugin);
			});
		}

		/// <summary>
		/// 按bootsrap优先级最低排序插件表
		/// </summary>
		private static void SortWithBootstrapLower(this List<PluginInfo> pluginInfos)
		{
			pluginInfos.Sort((p1, p2) =>
			{
				return p1.PluginAssembleInfo.BootStrapPlugin.CompareTo(p2.PluginAssembleInfo.BootStrapPlugin);
			});
		}

		/// <summary>
		/// 根据插件名，从磁盘dll中获取插件信息
		/// </summary>
		/// <returns>插件信息</returns>
		private static PluginInfo GetPluginInfoByPluginName(string pluginName)
		{
			string dllPath = Path.Combine(PluginPath, pluginName, $"{pluginName}.dll");
			if (!File.Exists(dllPath))
			{
				throw new FileNotFoundException("未找到插件dll文件", dllPath);
			}

			return GetPluginInfo(dllPath);
		}

		/// <summary>
		/// 根据dll获取其中的插件信息
		/// </summary>
		/// <param name="dllPath">dll文件路径</param>
		/// <returns>插件信息</returns>
		private static PluginInfo GetPluginInfo(string dllPath)
		{
			PluginInfo plugin = new PluginInfo();
			plugin.PluginName = Path.GetFileNameWithoutExtension(dllPath);
			plugin.PluginDllPath = dllPath;
			Assembly pluginAssembly = Assembly.UnsafeLoadFrom(dllPath);
			WinSupperPluginAttribute pluginAttribute = pluginAssembly.GetCustomAttribute<WinSupperPluginAttribute>();
			if (pluginAttribute == null)
			{
				throw new Exception("未在插件程序集中获取到[WinSupperPluginAttribute]特性，加载失败");
			}

			if (pluginAttribute.DependencySoftwareVersionCode > Conf.VersionCode)
			{
				Logger.Error($"当前软件版本[{Conf.VersionCode}]低于插件[{plugin.PluginName}]依赖的软件版本[{pluginAttribute.DependencySoftwareVersionCode}]");
				throw new Exception($"当前软件版本低于插件[{plugin.PluginName}]依赖的软件版本");
			}
			plugin.PluginAssembleInfo = pluginAttribute;

			List<Type> pluginInterfaceTypeList = new List<Type>();
			foreach (Type type in pluginAssembly.GetTypes())
			{
				if (!typeof(IWinSupperPlugin).IsAssignableFrom(type) || !type.IsClass || !type.IsPublic)
				{
					continue;
				}
				pluginInterfaceTypeList.Add(type);
			}
			if (pluginInterfaceTypeList.Count == 0)
			{
				throw new Exception("未在插件中找到实现IWinSupperPlugin的公开类，加载失败");
			}
			if (pluginInterfaceTypeList.Count > 1)
			{
				throw new Exception("在插件中找到多个实现IWinSupperPlugin的公开类，加载失败");
			}

			Type winSupperPluginType = pluginInterfaceTypeList.First();
			ConstructorInfo constructor = winSupperPluginType.GetConstructor(Type.EmptyTypes);
			if (constructor == null)
			{
				throw new Exception("未在IWinSupperPlugin的实现类中找到空参构造方法，初始化插件失败");
			}
			IWinSupperPlugin pluginInterface = (IWinSupperPlugin)constructor.Invoke(new object[0]);
			plugin.PluginInterface = pluginInterface;
			plugin.Loaded = false;

			return plugin;
		}

		/// <summary>
		/// 根据程序集特性获取插件详情
		/// </summary>
		/// <returns></returns>
		internal static PluginInfo GetPluginByAttribute(WinSupperPluginAttribute winSupperPluginAttribute)
		{
			if (winSupperPluginAttribute == null)
			{
				return null;
			}

			return _pluginInfos.FirstOrDefault(plugin => plugin.PluginAssembleInfo.IsSamePlugin(winSupperPluginAttribute));
		}

		/// <summary>
		/// 获取所有的本地插件信息
		/// </summary>
		/// <returns>本地插件信息</returns>
		internal static List<LocalPluginEntity> GetLocalPlugins()
		{
			return _pluginInfos.Select(plugin => LocalPluginEntity.FromPluginInfo(plugin)).ToList();
		}

		/// <summary>
		/// 根据插件名获取本地插件
		/// </summary>
		/// <param name="pluginName">插件名</param>
		internal static LocalPluginEntity GetLocalPlugin(string pluginName)
		{
			return _pluginInfos.Where(plugin => plugin.PluginName == pluginName)
				.Select(LocalPluginEntity.FromPluginInfo)
				.FirstOrDefault();
		}

		/// <summary>
		/// 检查插件状态是否正常并根据插件名获取插件信息
		/// </summary>
		private static PluginInfo CheckAndGetPluginInfo(string pluginName)
		{
			if (!Conf.DelayPluginHandleInfos.ContainsKey(pluginName))
			{
				Logger.Error($"未能从配置中获取到插件:[{pluginName}]相关信息。");
				CommonUtils.ShowErrorMsg($"未获取到插件:[{pluginName}]相关信息,程序退出");
				ApplicationUtil.Exit(1);
				return null;
			}

			SpecialHandlePluginInfo specialHandlePluginInfo = Conf.DelayPluginHandleInfos[pluginName];
			if (specialHandlePluginInfo.PluginStatus != PluginSpecialStatus.NORMAL &&
			    specialHandlePluginInfo.PluginStatus != PluginSpecialStatus.DISABLE)
			{
				Logger.Error($"插件:[{pluginName}]状态异常[{specialHandlePluginInfo.PluginStatus}]。");
				CommonUtils.ShowErrorMsg($"插件:[{pluginName}]状态异常,程序退出");
				ApplicationUtil.Exit(1);
				return null;
			}

			PluginInfo pluginInfo = _pluginInfos.FirstOrDefault(plugin => plugin.PluginName == pluginName);
			if (pluginInfo == null)
			{
				Logger.Error($"当前未加载插件:[{pluginName}]。");
				CommonUtils.ShowErrorMsg($"未知异常,程序退出");
				ApplicationUtil.Exit();
				return null;
			}

			return pluginInfo;
		}

		/// <summary>
		/// 切换插件禁用状态
		/// </summary>
		/// <param name="pluginName">插件名</param>
		internal static void ChangePluginDisableStatus(string pluginName)
		{
			Logger.Info($"开始切换插件禁用状态:[{pluginName}]");
			PluginInfo pluginInfo = CheckAndGetPluginInfo(pluginName);
			SpecialHandlePluginInfo specialHandlePluginInfo = Conf.DelayPluginHandleInfos[pluginName];

			if (specialHandlePluginInfo.PluginStatus == PluginSpecialStatus.NORMAL)
			{
				specialHandlePluginInfo.PluginStatus = PluginSpecialStatus.DISABLE;
				PluginStatueChanged?.Invoke(LocalPluginEntity.FromPluginInfo(pluginInfo));
				CommonUtils.ShowTipMsg("插件状态修改成功，重启程序后生效");
			}
			else
			{
				specialHandlePluginInfo.PluginStatus = PluginSpecialStatus.NORMAL;
				if (!pluginInfo.Loaded)
				{
					EnterPlugins();
				}
				PluginStatueChanged?.Invoke(LocalPluginEntity.FromPluginInfo(pluginInfo));
			}
			Conf.SaveConf();
		}

		/// <summary>
		/// 卸载插件
		/// </summary>
		/// <param name="pluginName">插件名</param>
		internal static void UninstallPlugin(string pluginName)
		{
			Logger.Info($"开始卸载插件:[{pluginName}]");
			PluginInfo pluginInfo = CheckAndGetPluginInfo(pluginName);
			SpecialHandlePluginInfo specialHandlePluginInfo = Conf.DelayPluginHandleInfos[pluginName];
			try
			{
				specialHandlePluginInfo.PluginStatus = PluginSpecialStatus.WAIT_DELETE;
				Conf.SaveConf();
				Exception excep = null;
				try
				{
					if (pluginInfo.Loaded)
					{
						pluginInfo.PluginInterface.Exit();
					}
				}
				catch (Exception e)
				{
					excep = e;
					Logger.Error($"退出插件[{pluginName}]失败: {e.Message}");
				}

				try
				{
					pluginInfo.PluginInterface.Uninstall();
					pluginInfo.Loaded = false;
				}
				catch (Exception e)
				{
					excep = e;
					Logger.Error($"卸载插件[{pluginName}]失败: {e.Message}");
				}
				for (var i = 0; i < _pluginInfos.Count; i++)
				{
					var plugin = _pluginInfos[i];
					if (plugin.PluginName == pluginName)
					{
						_pluginInfos.RemoveAt(i);
						PluginUninstalled?.Invoke(LocalPluginEntity.FromPluginInfo(plugin));
						break;
					}
				}

				if (excep != null)
				{
					throw excep;
				}

				MessageBoxResult messageBoxResult = MessageBox.Show($"已成功卸载插件:[{pluginName}],重启后将彻底清除，是否立即重启?", "提示",
					MessageBoxButton.OKCancel, MessageBoxImage.Information);
				if (messageBoxResult == MessageBoxResult.OK)
				{
					ApplicationUtil.Restart();
				}
			}
			catch (Exception e)
			{
				Logger.Error($"卸载插件[{pluginName}]失败: {e.Message}");
				CommonUtils.ShowErrorMsg($"卸载插件[{pluginName}]失败，程序退出");
				ApplicationUtil.Exit(1);
			}
		}

		/// <summary>
		/// 安装插件
		/// </summary>
		internal static void InstallPlugin(string pluginName)
		{
			Logger.Info($"开始安装插件:[{pluginName}]");
			string pluginZip = GeneratePluginPackagePath(pluginName);
			if (!File.Exists(pluginZip))
			{
				Logger.Error($"未获取到插件包，插件名[{pluginName}]，检测路径[{pluginZip}]，无法安装该插件");
				CommonUtils.ShowErrorMsg($"未获取到插件包，插件名[{pluginName}]，无法安装该插件");
				return;
			}

			try
			{
				DetectPluginZipValid(pluginName, pluginZip);
			}
			catch (Exception e)
			{
				try
				{
					File.Delete(pluginZip);
				}
				catch (Exception exception)
				{
					Logger.Error($"删除异常插件包[{pluginName}]失败: {exception.StackTrace}");
				}
				Logger.Error($"插件包[{pluginName}]格式不正确: {e.Message}");
				CommonUtils.ShowErrorMsg($"插件包[{pluginName}]格式不正确，无法安装该插件");
				return;
			}

			PluginInfo pluginInfo = _pluginInfos.FirstOrDefault(plugin => plugin.PluginName == pluginName);
			if (pluginInfo == null)
			{
				// 解压zip包进行插件安装
				string pluginPath = Path.Combine(PluginPath, pluginName);
				try
				{
					if (Directory.Exists(pluginPath))
					{
						Directory.Delete(pluginPath, true);
					}
					using (var zip = ZipFile.OpenRead(pluginZip))
					{
						zip.ExtractToDirectory(pluginPath, true);
					}
					Conf.DelayPluginHandleInfos[pluginName] = new SpecialHandlePluginInfo(pluginName, PluginSpecialStatus.INSTALL);
					_pluginInfos.Add(GetPluginInfoByPluginName(pluginName));
					EnterPlugins();
					Conf.SaveConf();
					File.Delete(pluginZip);
					CommonUtils.ShowTipMsgAsync($"插件[{pluginName}]安装成功");
				}
				catch (Exception e)
				{
					Conf.DelayPluginHandleInfos.Remove(pluginName);
					Logger.Error($"安装插件[{pluginName}]失败: {e.StackTrace}");
					CommonUtils.ShowErrorMsg($"安装插件[{pluginName}]失败，您可以通过日志查看失败原因");
				}
				return;
			}
			// 原插件已经存在需要先卸载老插件
			pluginInfo = CheckAndGetPluginInfo(pluginName);
			var specialHandlePluginInfo = Conf.DelayPluginHandleInfos[pluginName];
			try
			{
				specialHandlePluginInfo.PluginStatus = PluginSpecialStatus.WAIT_UPDATE;
				Conf.SaveConf();
				Exception excep = null;
				try
				{
					if (pluginInfo.Loaded)
					{
						pluginInfo.PluginInterface.Exit();
					}
				}
				catch (Exception e)
				{
					excep = e;
					Logger.Error($"退出插件[{pluginName}]失败: {e.Message}");
				}

				try
				{
					pluginInfo.PluginInterface.Uninstall();
					pluginInfo.Loaded = false;
				}
				catch (Exception e)
				{
					excep = e;
					Logger.Error($"卸载插件[{pluginName}]失败: {e.Message}");
				}
				for (var i = 0; i < _pluginInfos.Count; i++)
				{
					var plugin = _pluginInfos[i];
					if (plugin.PluginName == pluginName)
					{
						_pluginInfos.RemoveAt(i);
						PluginUninstalled?.Invoke(LocalPluginEntity.FromPluginInfo(plugin));
						break;
					}
				}

				if (excep != null)
				{
					throw excep;
				}
				ApplicationUtil.Restart();
			}
			catch (Exception e)
			{
				Logger.Error($"更新插件[{pluginName}]失败: {e.Message}");
				CommonUtils.ShowErrorMsg($"更新插件[{pluginName}]失败，程序退出");
				ApplicationUtil.Exit(1);
			}
		}
	}

	internal class PluginInfo
	{
		/// <summary>
		/// 插件接口
		/// </summary>
		public IWinSupperPlugin PluginInterface { get; set; }

		/// <summary>
		/// 插件程序集信息
		/// </summary>
		public WinSupperPluginAttribute PluginAssembleInfo { get; set; }

		/// <summary>
		/// 插件名
		/// </summary>
		public string PluginName { get; set; }

		/// <summary>
		/// 插件DLL路径
		/// </summary>
		public string PluginDllPath { get; set; }

		/// <summary>
		/// 是否加载了该插件
		/// </summary>
		public bool Loaded { get; set; }

		/// <summary>
		/// 是否禁用了该插件
		/// </summary>
		public bool Disabled
		{
			set => Conf.DelayPluginHandleInfos[PluginName].PluginStatus = PluginSpecialStatus.DISABLE;
			get
			{
				Conf.DelayPluginHandleInfos.TryGetValue(PluginName, out SpecialHandlePluginInfo specialHandlePluginInfo);
				return specialHandlePluginInfo != null && specialHandlePluginInfo.PluginStatus == PluginSpecialStatus.DISABLE;
			}
		}

	}
}
